本文将对Gradle的一些基本概念、用法进行总结,从而避免自己在Android开发过程中的“会而不知所以然”,关于Gradle的高阶用法可以见参考,本文就不再赘述;
基本概念
Wrapper
为了保证gradle版本的一致性,比如我们下载某个Android工程,编译运行前,wrapper会检查你本地是否存在gradle-wrapper.properties文件中声明的gradle版本,如果不存在,就会去下载,通常是个gradlew配合一起使用的,如下示例,可以帮助你更好的理解wrapper的概念;
1 | [min@TATEMIN-MB0:] gradle $ mkdir wrapper-demo # 创建一个空的wrapper-demo |
GradleUserHome
在Mac/Linux系统上,此目录即为~/.gradle目录,可以理解为gradle的workspace。
Daemon
因为JVM启动速度很慢,大约每次启动在10s左右,所以gradle为了解决这个问题,将gradle设计为如下结构:
大体的意思即使说,在启动gradle后会同时启动两个进程,一个Client,一个Daemon,Client负责具体的交互,比如命令的接收、日志的打印等等,Daemon负责具体的编译工作并和Client完成交互,Client端推出后,Daemon并不立即退出,如果期间没有新的Client发消息进来,会存活3小时左右,这样就避免了每次gradle启动时等待JVM启动的耗时,另外如果当前启动的Client版本和Daemon不一致,会重新启动一个Deamon。
Daemon 4.0以前,CI相关编译建议加上–no-daemon,因为此时Daemon并不稳定,后续版本无此问题。
Groovy基础
动态调用和MOP
MOP:元对象协议。由 Groovy 语言中的一种协议。该协议的出现为元编程提供了优雅的解决方案。而 MOP 机制的核心就是 MetaClass。
元编程:编写能够操作程序的程序,也包括操作程序自身,示例如下:
1 | string = 'hello' |
闭包
闭包是一个开放,匿名的代码块,可以接受参数,返回值并分配给变量;
闭包定义:{ [closureParameters -> ] statements },示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16//执行一句话
{ printf 'Hello World' }
//闭包有默认参数it,且不用申明
{ println it }
//闭包有默认参数it,申明了也无所谓
{ it -> println it }
// name是自定义的参数名
{ name -> println name }
//多个参数的闭包
{ String x, int y ->
println "hey ${x} the value is ${y}"
}Android示例:
1
2
3
4
5
6
7
8
9
10
11
12
13def android(closure) = {
closure()
}
def ext(closure) = {
closure()
}
android {
ext {
println("i am ext")
}
}
Gradle 构建
主要理解gradle的核心模型
Project
每个Gradle构建都由一个或多个Project组成。
Task
每个Project由一个或多个Task组成,Task代表构建执行的一些原子工作,比如编译某些类、创建JAR、生成Javadoc等等;
Lifecycle与Hook
Gradle构建的声明周期都分为三个不同的阶段.
Initialization
Gradle支持单项目和多项目构建. 在初始化阶段,Gradle确定将要参与构建的Project,并为每个Project创建一个Project实例(构建文件与Gradle交互的主要API.)
Configuration
在此阶段,将配置项目对象,执行作为构建一部分的所有项目的构建脚本.
Execution
Gradle确定要在配置阶段创建和配置的任务子集. 子集由传递给
gradle
命令的任务名称参数和当前目录确定. 然后Gradle执行每个选定的任务.
下面是一个非常好的例子可以理解一下:
1 | task("hello_world") { |
此脚本最后执行结果如下:
1 | [min@TATEMIN-MB0:] wrapper-demo $ ./gradlew task_2 |